// Author: wsfuyibing <682805@qq.com>
// Date: 2025-06-24

package operations

import (
	"context"
	"gitee.com/go-libs/db-xorm/db"
	"gitee.com/go-libs/log"
	"server/app/errs"
	"server/app/http/models"
	"server/app/http/services"
	"server/app/kind"
)

// Operations
// 余额操作公共方法.
type Operations struct{}

func (o *Operations) GetRecord(ctx context.Context, sess *db.Session, id int64) (record *models.BalanceRecords, err error) {
	var has bool
	if record, has, err = services.NewBalanceRecordsService(sess).Dao.GetById(ctx, id); err != nil {
		err = errs.ErrDatabaseQuery
		return
	}
	if !has {
		err = errs.ErrUserBalanceRecordNotFound
	}
	return
}

func (o *Operations) GetLatestRecord(_ context.Context, sess *db.Session, uid kind.UserId) (*models.BalanceRecords, bool, error) {
	var (
		err   error
		has   bool
		model = &models.BalanceRecords{}
	)

	// 1. 读取记录.
	//    取最后一条流水记录.
	if has, err = sess.Where("user_id = ?", uid).OrderBy("created_at DESC").Get(model); err != nil {
		err = errs.ErrUserStatisticNotFound
		return nil, false, err
	} else if !has {
		model = nil
	}

	// 2. 有流水账.
	return model, has, nil
}

func (o *Operations) GetUserStatistic(ctx context.Context, sess *db.Session, uid kind.UserId) (model *models.UserStatistic, err error) {
	var has bool

	// 1. 查询统计.
	if model, has, err = services.NewUserStatisticService(sess).Dao.GetByMap(ctx, map[string]any{
		"user_id": uid,
	}); err != nil {
		err = errs.ErrDatabaseQuery
		return
	}

	// 2. 无效数据.
	if !has {
		err = errs.ErrUserStatisticNotFound
	}
	return
}

func (o *Operations) SetUserBalance(ctx context.Context, sess *db.Session, uid kind.UserId, balance kind.Balance) (err error) {
	var affects int64
	if affects, err = services.NewUserStatisticService(sess).Dao.UpdateFieldsByMap(ctx, map[string]any{
		"balance": balance,
	}, map[string]any{
		"user_id": uid,
	}); err != nil {
		err = errs.ErrDatabaseQuery
	} else if affects > 0 {
		log.Infofc(ctx, `[lib][balance][user] 设置用户余额: user-id="%v", balance="%.02f"`, uid, balance)
	}
	return
}

func (o *Operations) SetUserFreezed(ctx context.Context, sess *db.Session, uid kind.UserId, balance kind.Balance) (err error) {
	var affects int64
	if affects, err = sess.Incr("balance_freezed", balance).Where("user_id = ?", uid).Update(models.UserStatistic{}); err != nil {
		err = errs.ErrDatabaseQuery
	} else if affects > 0 {
		log.Infofc(ctx, `[lib][balance][user] 冻结计算: user-id="%v", increment="%.02f"`, uid, balance)
	}
	return
}
